package com.cloud.common.security.framework.aspect;

import com.cloud.common.core.cons.APICons;
import com.cloud.common.core.enums.AuthEnums;
import com.cloud.common.core.model.entity.LoginInfo;
import com.cloud.common.core.utils.IpUtils;
import com.cloud.common.security.annotation.PreAuth;
import com.cloud.common.security.framework.aware.ApplicationUtils;
import com.cloud.common.security.utils.ApiUtils;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 权限校验
 * 拦截注解@PreAuth下的接口，统一权限校验
 *
 * @author yan
 */
@Aspect
@Component
public class AuthAspect {


    @Pointcut("@annotation(com.cloud.common.security.annotation.PreAuth)")
    @SuppressWarnings("EmptyMethod")
    public void pointCut() {
    }

    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = ApplicationUtils.getRequest();
        PreAuth preAuth = getAnnotationPreAuth(point);
        if (preAuth == null) {
            return point.proceed();
        }
        //检测是否有@ApiOperation注解
        checkAnnotationApi(request, point);
        request.setAttribute(APICons.API_BEGIN_TIME, System.currentTimeMillis());
        request.setAttribute(APICons.API_REQURL, request.getRequestURI());
        request.setAttribute(APICons.API_METHOD, request.getMethod());
        request.setAttribute(APICons.API_IP, IpUtils.getIpAddr(request));
        //鉴权
        AuthEnums auth = preAuth.value();
        if (auth == AuthEnums.PC_LOGIN) {
            request.setAttribute(APICons.API_OPER_TYPE, AuthEnums.PC_LOGIN.getValue());
        } else if (auth == AuthEnums.OPEN) {
            request.setAttribute(APICons.API_OPER_TYPE, AuthEnums.OPEN.getValue());
        } else if (auth == AuthEnums.PC_AUTH) {
            //PC鉴权
            request.setAttribute(APICons.API_OPER_TYPE, AuthEnums.PC_AUTH.getValue());
            request.setAttribute(APICons.API_OPER_NAME, ApiUtils.loginUser().getUserName());
        } else if (auth == AuthEnums.WX_MP_LOGIN) {
            request.setAttribute(APICons.API_OPER_TYPE, AuthEnums.WX_MP_LOGIN.getValue());
        } else if (auth == AuthEnums.WX_MP_AUTH) {
            //微信鉴权
            request.setAttribute(APICons.API_OPER_TYPE, AuthEnums.WX_MP_AUTH.getValue());
            request.setAttribute(APICons.API_OPER_NAME, "****");
        }

        return point.proceed();

    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private PreAuth getAnnotationPreAuth(JoinPoint point) {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(PreAuth.class);
        }
        return null;
    }

    /**
     * 检测是否有@ApiOperation注解
     *
     * @param request
     * @param point
     */
    private void checkAnnotationApi(HttpServletRequest request, JoinPoint point) {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            ApiOperation annotation = method.getAnnotation(ApiOperation.class);
            String annotationValue = "";
            if (annotation != null) {
                //注解上的描述
                annotationValue = annotation.value();
            }
            request.setAttribute(APICons.API_NAME, annotationValue);
        }
    }

}
